#include <iostream>
#include <ctime>
#include <vector>
#include <string>
#include <algorithm>

struct PCB {
    std::string pid_name;
    char state;
    int priority;
    int neededTime;
    int arrivalTime;
    int totalWaitTime;
    float responceRatio;

    PCB(const std::string& pname, char pstate, 
        int ppriority, int pneedTime, int parrival, int ptotaltime = 0)
        : pid_name(pname),
          state(pstate),
          priority(ppriority),
          neededTime(pneedTime),
          arrivalTime(parrival),
          totalWaitTime(ptotaltime),
          responceRatio(0.0)
    {}
    
    // 计算响应比
    void calculateResponceRatio(int currentTime) {
        int waitingTime = currentTime == 0 ? 0 : currentTime - arrivalTime;
        responceRatio = 1.0 + static_cast<float>(waitingTime) / neededTime;
    }

};

const static int pcb_num = 10;

bool cmp(PCB* x, PCB* y) {
    return x->responceRatio < y->responceRatio;
}

void HRRN_func(std::vector<PCB*>& pcbs) {
    int currentTime = 0;
    int totaltime = 0;
    while (!pcbs.empty()) {
        for (auto& pcb : pcbs) {
            pcb->calculateResponceRatio(currentTime);
        }

        std::sort(pcbs.begin(), pcbs.end(), cmp);
        PCB* back = pcbs.back();
        int waitingTime = currentTime == 0 ? 0 : currentTime - back->arrivalTime;
        std::cout << back->pid_name << " finished, waiting time is: " << waitingTime << std::endl;
        // 若是取出的第一个元素，需要加上第一个元素等待的时间
        if (pcbs.size() == pcb_num)
            currentTime += back->arrivalTime;

        currentTime += back->neededTime;
        totaltime += waitingTime;
        delete back;
        pcbs.pop_back();
    }

    float ave_time = static_cast<float>(totaltime) / pcb_num;
    std::cout << "Average waiting time is " << ave_time << std::endl;
}

int main() {
    srand(time(0));
    std::vector<PCB*> pcbs;

    for (int i = 0; i < pcb_num; i++) {
        const std::string name = "Process-" + std::to_string(i);
        int arrivalTime = 1 + rand() % 20;
        int needTime = 10 + rand() % 41;
        PCB* pcb = new PCB(name, 'w', 80, needTime, arrivalTime);
        pcbs.push_back(pcb);
        std::cout << "Generator: " << name 
            << " is generated, neededTime = " << needTime 
            << ", arrvalTime = " << arrivalTime << std::endl;
    }

    HRRN_func(pcbs);

    for (auto& p : pcbs)
        delete p;
    return 0;
}